package cn.edu.qzuie.artist.module.td.service.classinfo;

import cn.edu.qzuie.artist.framework.common.exception.ServiceException;
import cn.edu.qzuie.artist.module.td.controller.admin.major.vo.MajorAndDepartNameRespVo;
import cn.edu.qzuie.artist.module.td.dal.dataobject.department.DepartmentDO;
import cn.edu.qzuie.artist.module.td.dal.dataobject.major.MajorDO;
import cn.edu.qzuie.artist.module.td.dal.dataobject.school.SchoolDO;
import cn.edu.qzuie.artist.module.td.dal.dataobject.student.StudentDO;
import cn.edu.qzuie.artist.module.td.dal.mysql.student.StudentMapper;
import cn.edu.qzuie.artist.module.td.service.department.DepartmentService;
import cn.edu.qzuie.artist.module.td.service.major.MajorService;
import cn.edu.qzuie.artist.module.td.service.school.SchoolService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import cn.edu.qzuie.artist.module.td.controller.admin.classinfo.vo.*;
import cn.edu.qzuie.artist.module.td.dal.dataobject.classinfo.ClassinfoDO;
import cn.edu.qzuie.artist.framework.common.pojo.PageResult;
import cn.edu.qzuie.artist.framework.common.pojo.PageParam;
import cn.edu.qzuie.artist.framework.common.util.object.BeanUtils;

import cn.edu.qzuie.artist.module.td.dal.mysql.classinfo.ClassinfoMapper;

import javax.annotation.Resource;

import static cn.edu.qzuie.artist.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.edu.qzuie.artist.module.td.enums.ErrorCodeConstants.*;

/**
 * 班级 Service 实现类
 *
 * @author 泉信管理员
 */
@Service
@Validated
public class ClassinfoServiceImpl implements ClassinfoService {

    @Resource
    private ClassinfoMapper classinfoMapper;
    @Resource
    private MajorService majorService;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private SchoolService schoolService;

    @Resource
    private StudentMapper studentMapper;


    @Override
    public Long createClassinfo(ClassinfoSaveReqVO createReqVO) {
        // 插入
        ClassinfoDO classinfo = BeanUtils.toBean(createReqVO, ClassinfoDO.class);
        // 校验插入的班级是否存在
        if (isClassinfoExists(createReqVO.getClassinfoName(), createReqVO.getMajorId(),null)) {
            throw exception(CLASSINFO_ALREADY_EXISTS);
        }
        //插入
        classinfoMapper.insert(classinfo);
        // 返回
        return classinfo.getId();
    }


    @Override
    public void updateClassinfo(ClassinfoSaveReqVO updateReqVO) {
        // 校验存在
        validateClassinfoExists(updateReqVO.getId());
        // 校验插入的班级是否存在
        if (isClassinfoExists(updateReqVO.getClassinfoName(), updateReqVO.getMajorId(), updateReqVO.getId())) {
            throw exception(CLASSINFO_ALREADY_EXISTS);
        }
        // 更新
        ClassinfoDO updateObj = BeanUtils.toBean(updateReqVO, ClassinfoDO.class);
        classinfoMapper.updateById(updateObj);
    }
    /**
     * 校验班级信息是否已经存在
     *
     * @param classinfoName 班级名称
     * @param majorId       专业ID
     * @param excludeId     排除的ID，用于更新时检查
     * @return 是否存在
     */
    private boolean isClassinfoExists(String classinfoName, Long majorId,Long excludeId) {
        // 校验班级是否存在
        ClassinfoDO classinfo = classinfoMapper.selectOne(new cn.edu.qzuie.artist.framework.mybatis.core.query.LambdaQueryWrapperX<ClassinfoDO>()
                .eq(ClassinfoDO::getClassinfoName, classinfoName)
                .eq(ClassinfoDO::getDeleted,0)
                .eq(ClassinfoDO::getMajorId,majorId));
        return classinfo != null && !classinfo.getId().equals(excludeId);
    }



    @Override
    public void deleteClassinfo(Long id) {
        // 校验存在
        Long studentCount = studentMapper.selectCount(new cn.edu.qzuie.artist.framework.mybatis.core.query.LambdaQueryWrapperX<StudentDO>()
                .eq(StudentDO::getClassinfoId, id));
        if (studentCount == 0) {
            // 删除
            classinfoMapper.deleteById(id);
        } else {
            throw exception(Class_EXISTS_Student);
        }
    }

    private void validateClassinfoExists(Long id) {
        if (classinfoMapper.selectById(id) == null) {
            throw exception(CLASSINFO_NOT_EXISTS);
        }
    }



    @Override
    public ClassinfoDO getClassinfo(Long id) {
        return classinfoMapper.selectById(id);
    }

    @Override
    public PageResult<ClassinfoDO> getClassinfoPage(ClassinfoPageReqVO pageReqVO) {

        return classinfoMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<MajorAndSchoolNameRespVo> getMajorAndSchoolNameRespVoPage(ClassinfoPageReqVO pageReqVO) {
        // 获取分页结果
        PageResult<ClassinfoDO> pageResult = classinfoMapper.selectPage(pageReqVO);
        List<ClassinfoDO> classinfoDOList = pageResult.getList();

        // 如果列表为空，直接设置总条数为0，并返回
        if (classinfoDOList.isEmpty()) {
            return new PageResult<>(Collections.emptyList(), 0L);
        }

        // 初始化结果列表
        List<MajorAndSchoolNameRespVo> respVoList = new ArrayList<>(classinfoDOList.size());

        // 遍历classinfoDOList，构建MajorAndSchoolNameRespVo对象并添加到结果列表中
        for (ClassinfoDO classinfoDO : classinfoDOList) {
            MajorAndSchoolNameRespVo respVo = new MajorAndSchoolNameRespVo();
            BeanUtils.copyProperties(classinfoDO, respVo);
            MajorDO majorDO = majorService.getMajor(classinfoDO.getMajorId());
            if (majorDO != null) {
                DepartmentDO departmentDO = departmentService.getDepartment(majorDO.getDepartId());
                if (departmentDO != null) {
                    SchoolDO schoolDO = schoolService.getSchool(departmentDO.getSchoolId());
                    if (schoolDO != null) {
                        respVo.setSchoolName(schoolDO.getSchoolName());
                        respVo.setMajorName(majorDO.getMajorName());
                        respVoList.add(respVo);
                    }
                }
            }
        }

        // 设置返回结果的列表和总条数
        return new PageResult<>(respVoList, pageResult.getTotal());
    }
}